package com.ruoyi.pingan.fymodule.goodsinfo.goods.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.pingan.enums.CommonSortOrderEnum;
import com.ruoyi.pingan.exception.CommonException;
import com.ruoyi.pingan.fymodule.goodsinfo.goods.entity.SxoGoods;
import com.ruoyi.pingan.fymodule.goodsinfo.goods.mapper.SxoGoodsMapper;
import com.ruoyi.pingan.fymodule.goodsinfo.goods.param.SxoGoodsAddParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goods.param.SxoGoodsEditParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goods.param.SxoGoodsIdParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goods.param.SxoGoodsPageParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goods.service.SxoGoodsService;
import com.ruoyi.pingan.page.CommonPageRequest;
import com.ruoyi.pingan.util.CommonDownloadUtil;
import com.ruoyi.pingan.util.CommonResponseUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;


import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 商品信息Service接口实现类
 *
 * @author wangy
 * @date  2025/07/25 11:54
 **/
@Service
public class SxoGoodsServiceImpl extends ServiceImpl<SxoGoodsMapper, SxoGoods> implements SxoGoodsService {

    @Override
    public Page<SxoGoods> page(SxoGoodsPageParam sxoGoodsPageParam) {
        QueryWrapper<SxoGoods> queryWrapper = new QueryWrapper<SxoGoods>().checkSqlInjection();
        if(ObjectUtil.isAllNotEmpty(sxoGoodsPageParam.getSortField(), sxoGoodsPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(sxoGoodsPageParam.getSortOrder());
            queryWrapper.orderBy(true, sxoGoodsPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(sxoGoodsPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(SxoGoods::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(SxoGoodsAddParam sxoGoodsAddParam) {
        SxoGoods sxoGoods = BeanUtil.toBean(sxoGoodsAddParam, SxoGoods.class);
        this.save(sxoGoods);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(SxoGoodsEditParam sxoGoodsEditParam) {
        SxoGoods sxoGoods = this.queryEntity(sxoGoodsEditParam.getId());
        BeanUtil.copyProperties(sxoGoodsEditParam, sxoGoods);
        this.updateById(sxoGoods);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<SxoGoodsIdParam> sxoGoodsIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(sxoGoodsIdParamList, SxoGoodsIdParam::getId));
    }

    @Override
    public SxoGoods detail(SxoGoodsIdParam sxoGoodsIdParam) {
        return this.queryEntity(sxoGoodsIdParam.getId());
    }

    @Override
    public SxoGoods queryEntity(String id) {
        SxoGoods sxoGoods = this.getById(id);
        if(ObjectUtil.isEmpty(sxoGoods)) {
            throw new CommonException("商品信息不存在，id值为：{}", id);
        }
        return sxoGoods;
    }

    @Override
    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<SxoGoodsEditParam> dataList = CollectionUtil.newArrayList();
         String fileName = "商品信息导入模板_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), SxoGoodsEditParam.class).sheet("商品信息").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 商品信息导入模板下载失败：", e);
         CommonResponseUtil.renderError(response, "商品信息导入模板下载失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject importData(MultipartFile file) {
        try {
            int successCount = 0;
            int errorCount = 0;
            JSONArray errorDetail = JSONUtil.createArray();
            // 创建临时文件
            File tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() +
                    FileUtil.FILE_SEPARATOR + "sxoGoodsImportTemplate.xlsx"));
            // 读取excel
            List<SxoGoodsEditParam> sxoGoodsEditParamList =  EasyExcel.read(tempFile).head(SxoGoodsEditParam.class).sheet()
                    .headRowNumber(1).doReadSync();
            List<SxoGoods> allDataList = this.list();
            for (int i = 0; i < sxoGoodsEditParamList.size(); i++) {
                JSONObject jsonObject = this.doImport(allDataList, sxoGoodsEditParamList.get(i), i);
                if(jsonObject.getBool("success")) {
                    successCount += 1;
                } else {
                    errorCount += 1;
                    errorDetail.add(jsonObject);
                }
            }
            return JSONUtil.createObj()
                    .set("totalCount", sxoGoodsEditParamList.size())
                    .set("successCount", successCount)
                    .set("errorCount", errorCount)
                    .set("errorDetail", errorDetail);
        } catch (Exception e) {
            log.error(">>> 商品信息导入失败：", e);
            throw new CommonException("商品信息导入失败");
        }
    }

    public JSONObject doImport(List<SxoGoods> allDataList, SxoGoodsEditParam sxoGoodsEditParam, int i) {
        String id = sxoGoodsEditParam.getId();
        if(ObjectUtil.hasEmpty(id)) {
            return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "必填字段存在空值");
        } else {
            try {
                int index = CollStreamUtil.toList(allDataList, SxoGoods::getId).indexOf(sxoGoodsEditParam.getId());
                SxoGoods sxoGoods;
                boolean isAdd = false;
                if(index == -1) {
                    isAdd = true;
                    sxoGoods = new SxoGoods();
                } else {
                    sxoGoods = allDataList.get(index);
                }
                BeanUtil.copyProperties(sxoGoodsEditParam, sxoGoods);
                if(isAdd) {
                    allDataList.add(sxoGoods);
                } else {
                    allDataList.remove(index);
                    allDataList.add(index, sxoGoods);
                }
                this.saveOrUpdate(sxoGoods);
                return JSONUtil.createObj().set("success", true);
            } catch (Exception e) {
              log.error(">>> 数据导入异常：", e);
              return JSONUtil.createObj().set("success", false).set("index", i + 1).set("msg", "数据导入异常");
            }
        }
    }



    @Override
    public void exportData(List<SxoGoodsIdParam> sxoGoodsIdParamList, HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<SxoGoodsEditParam> dataList;
         if(ObjectUtil.isNotEmpty(sxoGoodsIdParamList)) {
            List<String> idList = CollStreamUtil.toList(sxoGoodsIdParamList, SxoGoodsIdParam::getId);
            dataList = BeanUtil.copyToList(this.listByIds(idList), SxoGoodsEditParam.class);
         } else {
            dataList = BeanUtil.copyToList(this.list(), SxoGoodsEditParam.class);
         }
         String fileName = "商品信息_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), SxoGoodsEditParam.class).sheet("商品信息").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 商品信息导出失败：", e);
         CommonResponseUtil.renderError(response, "商品信息导出失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }
}
